<template>
  <a-modal
    :width="1032"
    :visible="visible"
    @cancel="handleClose"
    @ok="handleOk"
    :maskClosable="false"
    :destroyOnClose="true"
    :confirmLoading="saveLoading"
    centered
    wrapClassName="modalRefLayer-01"
  >
    <template #title>
      楼层2D平面图模型
      <a-space>
        <a-button v-if="canvasInstance && !canvasInstance.readonly" size="small" type="link" style="margin-left: 8px" @click.stop="showInstructions">查看操作说明</a-button>
        <a-button size="small" type="link" @click.stop="changeImage">设置背景图</a-button>
      </a-space>
    </template>
    <div class="content">
      <div class="draw-content" ref="containerWrapRef">
        <!--  画布   -->
        <canvas class="canvas-container"></canvas>
        <!--  遮罩层   -->
        <div class="container-mask" ref="containerMaskRef"></div>
        <!--   绑定房间   -->
        <div
          class="bind-wrap"
          ref="bindWrapRef"
          v-if="bindRoomVisible"
        >
          <div style="display: flex; align-items: center">
            <a-select
              v-model:value="currentBindRoom"
              style="width: 150px;"
              size="small"
              placeholder="请选择"
              :allowClear="true"
            >
              <a-select-option
                v-for="(item, index) of roomList"
                :key="index"
                :value="item.id"
              >{{ item.room_name }}</a-select-option
              >
            </a-select>
            <a-button
              type="primary"
              size="small"
              style="margin-left: 5px"
              @click="bindRoomSave"
            >
              确定
            </a-button>
          </div>
        </div>
      </div>
      <!--  操作区域  -->
      <div class="draw-operate">
        <a-row type="flex" justify="space-between">
          <a-space>
            <template v-if="canvasInstance && canvasInstance.readonly" >
              <a-button size="small" type="primary" v-if="!isBindMode" @click.stop="startDraw()">开始绘制</a-button>
              <a-button size="small" type="primary" @click.stop="handleBindMode()">{{isBindMode ? '退出标记房间' : '标记房间'}}</a-button>
            </template>
            <template v-else>
              <a-button size="small" type="primary" @click.stop="shapeCreate(1)">创建矩形</a-button>
              <a-button size="small" type="primary" @click.stop="shapeCreate(2)">创建多边形</a-button>
              <a-button size="small" type="primary" @click.stop="shapeCreate(0)">完成绘制/拖动</a-button>
              <a-button size="small" type="primary" @click="canvasFitZoom">
                还原绘制区域大小
              </a-button>
            </template>
          </a-space>
          <a-button v-if="canvasInstance && !canvasInstance.readonly" size="small" type="primary" @click.stop="closeDraw()">退出绘制</a-button>
        </a-row>

      </div>
    </div>


    <!-- 操作说明 -->
    <a-modal
      v-model:visible="instructionsVisible"
      title="操作说明"
      :footer="null"
      centered
      @cancel="instructionsVisible = false"
    >
      <p>
        1.
        创建多边形：鼠标左键单击添加点，双击闭合完成创建，Esc退出创建，Backspace
        退一步删除选择点。
      </p>
      <p>2. 拖动：按住鼠标右键拖动画布。</p>
      <p>3. 缩放：鼠标滚轮缩放画布</p>
      <p>4. 删除：选中形状，Backspace删除</p>
    </a-modal>


    <!--  设置背景图  -->
    <SettingBgModal
      :visible="uploadBgVisible"
      :bgUrl="drawPolyBg"
      @handleClose="uploadBgVisible = false"
      @handleSuccess="handleUploadBgSuccess"
    />

  </a-modal>

</template>

<script>
import {
  computed,
  defineComponent,
  nextTick,
  reactive,
  ref,
  toRaw,
  toRefs,
  watch,
} from "vue";
import CanvasSelect from "canvas-select";
import _ from "lodash";
import utils from "@/common/utils/utils";
import request from "@/common/utils/request";
import { uuid } from 'vue-uuid';
import {PlusOutlined} from "@ant-design/icons-vue";
import {message} from "ant-design-vue";
import SettingBgModal from "@/views/village/BuildingManage/modules/SettingBgModal.vue";

export default defineComponent({
  name: "Layer2DEdit",
  components: {
    PlusOutlined,
    CanvasSelect,
    SettingBgModal,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    roomList: {
      type: Array,
      default: () => {
        return [];
      },
    },
    editInfo: {
      type:  [Object, Array, undefined],
      default: undefined,
    },
    saveRequest: {
      type: Boolean,
      default: false,
    },
    villageId: {
      type: [String, Number],
      default: 0,
    },
    layerId: {
      type: [String, Number],
      default: 0,
    }
  },
  setup(props, { emit }) {

    const BgImg =  utils.staticPath + 'images/common/two_dimensional_bg.png';
    const state = reactive({
      canvasInstance: null,
      drawPolyData: [], //绘制图形数据
      instructionsVisible: false,
      defaultOptions: [], // 默认的配置
      bindWrapRef: null,
      bindRoomVisible: false, //绑定楼宇pop是否显示
      currentDrawPoly: {}, //选中的绘制图形  bind-active
      currentBindRoom: undefined, //选中的绘制图形  绑定的房间
      isBindMode: false, // 标记模式
      containerMaskRef: null,
      saveLoading: false,
      uploadBgVisible: false,
      drawPolyBg: '',
    });



    const handleClose = () => {
      emit('handleClose')
    };

    // 点击确定的回调
    const handleOk = () => {
      let data = _.cloneDeep(state.drawPolyData);
      data = data.map((v) => {
        delete v.bindRoomInfo;
        delete v.strokeStyle;
        delete v.roomLineColor;
        delete v.fillStyle;
        delete v.roomFillColor;
        delete v.label;
        delete v.labelFont;
        v.active = false;
        return v;
      })
      let params = {
        coorList: data,
        bg_img: state.drawPolyBg,
      }
      if (props.saveRequest) {
        // 请求接口保存
        state.saveLoading = true;
        request.put("/village", "/project/layer/two_dimensional", {
          id: props.layerId,
          village_id: props.villageId,
          two_dimensional: params
        }).then(() => {
          state.saveLoading = false;
          emit('handleOK');
        })
      } else {
        emit('handleOK', params);
      }
    };

    const hideBindRoom = () => {
      state.bindRoomVisible = false;
      state.currentBindRoom = undefined;
      state.currentDrawPoly = {};
      state.drawPolyData.forEach((poly) => {
        poly.active = false;
        poly.fillStyle = poly.roomFillColor || '#fff';
        poly.strokeStyle = poly.roomLineColor || '#2681f3';
      });
      state.canvasInstance.update();
    };

    const showBindRoom = () => {
      let centerX = state.canvasInstance.mouse[0];
      let centerY = state.canvasInstance.mouse[1];
      let transform = "translate(-50%, -50%)";
      let picTopRight = [
        state.canvasInstance.originX + state.canvasInstance.IMAGE_WIDTH,
        state.canvasInstance.IMAGE_HEIGHT,
      ];
      if (centerX + 280 >= picTopRight[0]) {
        if (centerY < 240) {
          //如果点击位置离右上角太近，移动到鼠标左下方显示
          transform = "translate(-100%, 0)";
        } else {
          //如果点击位置离右下角太近，移动到鼠标左上方显示
          transform = "translate(-100%, -100%)";
        }
      }
      state.bindRoomVisible = true;
      nextTick(() => {
        state.bindWrapRef.style.top = `${centerY}px`;
        state.bindWrapRef.style.left = `${centerX}px`;
        state.bindWrapRef.style.transform = transform;
      });
    };

    const initCanvasInstance = () => {
      state.canvasInstance = new CanvasSelect(".canvas-container", state.drawPolyBg || BgImg);
      // 加载数据
      state.canvasInstance.setData(state.defaultOptions);
      // 0 不创建(默认)，1创建矩形，2创建多边形，3点标注，4折线标注，5圆形标注
      state.canvasInstance.fillStyle = "rgba(255, 255, 255)";
      state.canvasInstance.strokeStyle = "#2681f3";

      state.canvasInstance.createType = 0;
      state.canvasInstance.ctrlRadius = 3;
      state.canvasInstance.scrollZoom = true;
      state.canvasInstance.activeFillStyle = "#d3e3fd";
      state.canvasInstance.activeStrokeStyle = "#2681f3";
      state.canvasInstance.readonly = true;
      state.canvasInstance.labelFont = '14px sans-serif';

      state.canvasInstance.on("select", (info) => {
        console.log("select", info);
        // 可对选中对参数info进行修改
        // 修改标签：info.label="hello"
        // 单个形状修改填充颜色：info.fillStyle="#0f0"
        // 然后调用instance.update()更新视图
        if (state.isBindMode) {
          // 只读情况下可以绑定房间
          if (info) {
            state.drawPolyData.forEach((poly) => {
              if (poly.uuid == info.uuid) {
                state.currentDrawPoly = info;
                //默认标注类型楼宇
                state.currentBindRoom = state.currentDrawPoly?.bindRoomId || undefined;
                poly.active = true;
                poly.fillStyle = "rgba(41, 150, 255, 0.5)";
                poly.strokeStyle = "#fff";
              } else {
                poly.active = false;
                poly.fillStyle = poly.roomFillColor || '#fff';
                poly.strokeStyle = poly.roomLineColor || '#2681f3';
              }
            });
            showBindRoom();
          } else {
            hideBindRoom();
          }
        }
      });

      state.canvasInstance.on("updated", (result) => {
        state.drawPolyData = [...result];
      });
    }

    const shapeCreate = (num) => {
      state.canvasInstance.createType = num;
    };

    const canvasFitZoom = () => {
      state.canvasInstance.fitZoom();
    };

    const closeDraw = () => {
      state.canvasInstance.readonly = true;
      //画布大小复原
      state.canvasInstance.fitZoom();
      //锁定画布
      state.canvasInstance.lock = true;
      //遮罩层鼠标事件开启，屏蔽canvas鼠标事件
      state.containerMaskRef.style.pointerEvents = "all";
      hideBindRoom();
    };

    const startDraw = () => {
      // 开始绘制
      //开启画布
      state.canvasInstance.lock = false;
      state.canvasInstance.readonly = false;
      state.canvasInstance.createType = 0;
      //遮罩层鼠标事件关闭，放开canvas鼠标事件
      state.containerMaskRef.style.pointerEvents = "none";
      state.canvasInstance.scrollZoom = true;
    };

    const showInstructions = () => {
      state.instructionsVisible = true;
    };

    const setCurrentRoomStyle = (info = {}, roomId) => {
      if (roomId) {
        let roomInfo = props.roomList.find((v) => v.id == roomId);
        info.bindRoomId = roomInfo.id;
        info.bindRoomInfo = roomInfo;
        let bindColor = roomInfo?.roomColor;
        if (bindColor) {
          let roomFillColor = utils.getHexOpacityColor({color: bindColor, opacity: 0.9});
          info.strokeStyle = "#fff";
          info.roomLineColor = "#fff";
          info.fillStyle = roomFillColor;
          info.roomFillColor = roomFillColor;
        }
        info.label = roomInfo?.room_name || '';
        info.labelFont = '14px sans-serif';
      } else {
        info.label = '';
        info.strokeStyle = "#2681f3";
        info.fillStyle = '#fff';
        delete info.bindRoomId;
        delete info.bindRoomInfo;
        delete info.roomLineColor;
        delete info.roomFillColor;
      }

      return info;
    }

    const bindRoomSave = () => {
      state.currentDrawPoly = setCurrentRoomStyle(state.currentDrawPoly, state.currentBindRoom);
      hideBindRoom()
    };

    const handleBindMode = () => {
      state.isBindMode = !state.isBindMode;
      if (state.isBindMode) {
        // 开始标记
        //开启画布
        state.canvasInstance.lock = false;
        //遮罩层鼠标事件关闭，放开canvas鼠标事件
        state.containerMaskRef.style.pointerEvents = "none";
        // 禁止画布缩放
        state.canvasInstance.scrollZoom = false;
      } else {
        // 退出标记
        //画布大小复原
        state.canvasInstance.fitZoom();
        //锁定画布
        state.canvasInstance.lock = true;
        //遮罩层鼠标事件开启，屏蔽canvas鼠标事件
        state.containerMaskRef.style.pointerEvents = "all";
        hideBindRoom();
      }
    };

    const parseRatio = (number, decimal = 2) => {
      return (Math.floor(number * 100) / 100).toFixed(decimal);
    };

    /* 设置背景图 */
    const changeImage = () => {
      state.uploadBgVisible = true;
    };

    const handleUploadBgSuccess = (url) => {
      state.drawPolyBg = url;
      if  (state.canvasInstance) {
        state.canvasInstance.setImage(state.drawPolyBg || BgImg);
      } else {
        state.canvasInstance = new CanvasSelect(".canvas-container", state.drawPolyBg || BgImg);
      }
      state.uploadBgVisible = false;
    };


    watch(
      () => props.visible,
      (val) => {
        if (val) {
          // 初始化（房间信息（颜色名称等））
          let editArr = _.cloneDeep(props.editInfo?.coorList);
          state.drawPolyBg = props.editInfo?.bg_img || '';
          if (_.isEmpty(editArr)) {
            editArr = [];
            let percentTotal = 100;
            let percentRow = 1;
            let percentCol = 0;
            let _roomList = (props.roomList || []).map((v) => {
              percentTotal = percentTotal - Number(v.areaRatio);
              if (percentTotal < 0) {
                percentTotal = 100;
                percentRow ++;
                percentCol = 1;
              } else {
                percentCol ++;
              }
              return { id: v.id, areaRatio: Number(v.areaRatio), row: percentRow, col: percentCol};
            });
            let gapWidth = 14;
            let colHeight = 60;
            for (let i = 0; i < _roomList.length; i++) {
              let columnsTotal = _roomList.filter((item) => item.row == _roomList[i].row);
              let widthTotal = 1000 - ((columnsTotal.length + 1)*gapWidth);
              let colWidth = Number(parseRatio(
                (widthTotal * _roomList[i].areaRatio)/100
              ));
              let beforeTotalArea = 0;
              if (_roomList[i].col > 1) {
                columnsTotal.forEach((item) => {
                  if (item.col < _roomList[i].col) {
                    beforeTotalArea = Number(beforeTotalArea) + Number(parseRatio(
                      (widthTotal * item.areaRatio)/100
                    ));
                  }
                })
              }
              let surplusHeight = 666;

              if (_roomList[i].row > 1) {
                surplusHeight = 666 - (_roomList[i].row - 1) * colHeight - (_roomList[i].row + 1) * gapWidth;
              }

              if (surplusHeight < colHeight) {
                break;
              }
              _roomList[i].coor = [
                [(gapWidth * _roomList[i].col) + beforeTotalArea, _roomList[i].row*gapWidth + (_roomList[i].row - 1) * colHeight],
                [(gapWidth * _roomList[i].col) + beforeTotalArea + colWidth, gapWidth * _roomList[i].row + _roomList[i].row * colHeight],
              ];
              // console.log(beforeTotalArea,colWidth,widthTotal,_roomList[i].coor, 'beforeTotalArea====')
              _roomList[i].index = i;
              _roomList[i].type = 1;
              _roomList[i].uuid = uuid.v4();
              _roomList[i].creating = false;
              _roomList[i].dragging = false;
              _roomList[i].active = false;
              setCurrentRoomStyle(
                _roomList[i],
                _roomList[i].id,
              );
              editArr.push(_roomList[i]);
            }
          } else {
            (editArr || []).forEach((v) => {
              if (v.bindRoomId) {
                v = setCurrentRoomStyle(v, v.bindRoomId)
              }
            })
          }
          state.defaultOptions = editArr;
          nextTick(() => {
            document.getElementsByClassName('modalRefLayer-01')[0].removeAttribute('tabindex')
            initCanvasInstance();
          });
        } else {
          state.defaultOptions = [];
          state.drawPolyBg = '';
          if (state.canvasInstance) {
            state.canvasInstance.createType = 0;
            state.canvasInstance.destroy();
            state.canvasInstance = null;
          }
          state.drawPolyData = [];
          state.bindRoomVisible = false;
          state.currentDrawPoly = {};
          state.currentBindRoom = undefined;
          state.isBindMode = false;
          state.saveLoading = false;
        }
      }
    );



    return {
      ...toRefs(state),
      handleClose,
      handleOk,
      shapeCreate,
      canvasFitZoom,
      closeDraw,
      startDraw,
      showInstructions,
      bindRoomSave,
      handleBindMode,
      changeImage,
      handleUploadBgSuccess,
    };
  },
});
</script>

<style lang="less" scoped>
.content {
  width: 100%;
  position: relative;
}
.draw-content {
  height: 666px;
  width: 1000px;
  position: relative;
}

.container-mask {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  z-index: 9;
  //   pointer-events: none;
}
.canvas-container {
  background-color: #fff;
  width: 100%;
  height: 100%;
}
.draw-operate {
  margin-top: 16px;
  //display: flex;
}
.bind-wrap {
  position: absolute;
  z-index: 10;
  transform: translate(-50%, -50%);
}

</style>
